#include "oled_sprintf.h"

// 缓冲区定义
char lcd_line_buffer[MAX_LINE][MAX_COL];       // 当前帧要显示的内容
char lcd_line_shadow[MAX_LINE][MAX_COL];       // 上一帧内容，用于比较差异

volatile uint8_t menu_mode = 0;
uint8_t cursor_0 = 3;
uint8_t cursor_1 = 1;
uint8_t cursor_2 = 1;

//==================== 实际 SPI 写屏函数 ====================//
void oled_sprintf(uint16_t line, uint16_t col, const char *format, ...)
{
    #define BUFFER_SIZE 256
    char str[BUFFER_SIZE];

    va_list args;
    va_start(args, format);
    int len = vsnprintf(str, BUFFER_SIZE, format, args);
    va_end(args);

    if (len > 0)
    {
        uint16_t fc = WHITE;
        uint16_t bc = BLACK;
        uint8_t sizey = FONT_H;
        uint8_t mode = 0;

        uint16_t x_pix = col * FONT_W;
        uint16_t y_pix = line * FONT_H;

        LCD_ShowString(x_pix, y_pix, (const uint8_t *)str, fc, bc, sizey, mode);
    }
}

//==================== 缓存更新函数 ====================//
void oled_sprintf_buffer(uint16_t line, uint16_t col, const char *format, ...)
{
    if (line >= MAX_LINE || col >= MAX_COL) return;

    char *dst = lcd_line_buffer[line] + col;
    size_t maxlen = MAX_COL - col;

    va_list args;
    va_start(args, format);
    vsnprintf(dst, maxlen, format, args);
    va_end(args);
}

//==================== 缓存→屏幕 刷新一行 ====================//
void lcd_refresh_task(void)
{
    static uint8_t line = 0;

    if (strcmp(lcd_line_buffer[line], lcd_line_shadow[line]) != 0)
    {
        oled_sprintf(line, 0, "%s", lcd_line_buffer[line]);
        strcpy(lcd_line_shadow[line], lcd_line_buffer[line]);
    }

    line++;
    if (line >= MAX_LINE)
        line = 0;
}

//==================== 屏幕数据更新函数（只更新 buffer） ====================//
void lcd_proc(void)
{
    static int last_menu_mode = -1; // 静态变量记录上一次的菜单模式
    static int last_cursor_0 = -1;
    static int last_cursor_1 = -1;  // 记录上一次的光标位置
    static int last_cursor_2 = -1;
    
    
    // 可选：每帧清空 buffer
    for (int i = 0; i < MAX_LINE; i++)
        memset(lcd_line_buffer[i], ' ', MAX_COL - 1), lcd_line_buffer[i][MAX_COL - 1] = '\0';

    // 只有在菜单模式改变时才清屏
    if (last_menu_mode != menu_mode)
    {
        LCD_Fill(0, 0, 160, 160, BLACK); //清屏
        last_menu_mode = menu_mode; // 更新记录的模式
    }

    if (menu_mode == 0)
    {
        oled_sprintf_buffer(0, 1, "page:%d,mode:%d", menu_mode, car_mode);
        oled_sprintf_buffer(1, 1, "Yaw: %.2f  " , wit_data.yaw);
        oled_sprintf_buffer(2, 1, "Dx:%d  Dy:%d     ", XY_Servo.x_delta, XY_Servo.y_delta);
        oled_sprintf_buffer(3, 2, "mission: %d ",mission_num);
        oled_sprintf_buffer(4, 2, "N_round: %d ",N_round);
        oled_sprintf_buffer(5, 1, " L0 R1 :%d",turn_flag);
        oled_sprintf_buffer(6, 1, "EA:%d    ", Encoder_Now[0]);
        oled_sprintf_buffer(7, 1, "EB:%d    ", Encoder_Now[3]);
        oled_sprintf_buffer(8, 0, "%d %d %d %d %d %d %d %d", sensor_buffer[1], sensor_buffer[2], sensor_buffer[3], sensor_buffer[4],
				 sensor_buffer[5], sensor_buffer[6], sensor_buffer[7], sensor_buffer[8]);
        oled_sprintf_buffer(9, 1, " %.2f ", gw_offset);

        if (last_cursor_0 != -1 && last_cursor_0 != cursor_0)
        {
            oled_sprintf(last_cursor_0, CURSOR_COL, " ");
        }// 清除上一个光标位置

        // 显示当前光标
        oled_sprintf(cursor_0, CURSOR_COL, "*");
        last_cursor_0 = cursor_0;  // 更新光标记录
    }
    else if (menu_mode == 1)
    {
        oled_sprintf(0, 2, "page:%d", menu_mode);
        oled_sprintf_buffer(1, 2, "Yp:%.2f", PID_data_array[3][0]);  
        oled_sprintf_buffer(2, 2, "Yi:%.2f", PID_data_array[3][1]);  
        oled_sprintf_buffer(3, 2, "Yd:%.2f", PID_data_array[3][2]);  
        oled_sprintf_buffer(4, 2, "Gp:%.2f", PID_data_array[1][0]);  
        oled_sprintf_buffer(5, 2, "Gi:%.2f", PID_data_array[1][1]);  
        oled_sprintf_buffer(6, 2, "Gd:%.2f", PID_data_array[1][2]); 
        oled_sprintf_buffer(7, 2, "Sp:%.2f", PID_data_array[2][0]);
        oled_sprintf_buffer(8, 2, "Si:%.2f", PID_data_array[2][1]);
        oled_sprintf_buffer(9, 2, "Sd:%.2f", PID_data_array[2][2]);
        
        if (last_cursor_1 != -1 && last_cursor_1 != cursor_1)
        {
            oled_sprintf(last_cursor_1, CURSOR_COL, " ");
        }// 清除上一个光标位置
        
        // 显示当前光标
        oled_sprintf(cursor_1, CURSOR_COL, "*");
        last_cursor_1 = cursor_1;  // 更新光标记录
    }
    else if(menu_mode == 2)
    {
        oled_sprintf_buffer(0, 2, "page:%d", menu_mode);
        oled_sprintf_buffer(1, 2, "Se1_A:%.2f", servo1_angle);
        oled_sprintf_buffer(2, 2, "Se2_A:%.2f", servo3_angle);
        oled_sprintf_buffer(3, 2, "Se1_x:%.2f", servo1_angle);
        oled_sprintf_buffer(4, 2, "Se3_x:%.2f", servo3_angle);

        if (last_cursor_2 != -1 && last_cursor_2 != cursor_2)
        {
            oled_sprintf(last_cursor_2, CURSOR_COL, " ");
        }
        oled_sprintf(cursor_2, CURSOR_COL, "*");
        last_cursor_2 = cursor_2;
    }
    else if (menu_mode == 3)
    {
        oled_sprintf_buffer(0, 2, "page: %d", menu_mode);
        oled_sprintf_buffer(1, 2, "SET_GW_MODE");
    }
    else 
    {
        oled_sprintf_buffer(0, 2, "page: %d", menu_mode);
        oled_sprintf_buffer(1, 2, "undefined page   ");
        for (int i = 2; i < 9; i++)
            oled_sprintf_buffer(i, 2, "undefined data   ");
    }
}
